package com.company.earthquake;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;

public class EarthquakeProvider extends ContentProvider {
	
	public static final Uri CONTENT_URI = Uri.parse("content://com.company.provider.earthquake/earthquakes");
	private SQLiteDatabase earthquakeDB;
	
	private static final String TAG = "EarthquakeProvider";
	private static final String DATABASE_NAME = "earthquakes.db";
	private static final String EARTHQUAKE_TABLE = "earthquakes";
	private static final int DATABASE_VERSION = 1;
	
	// column name
	public static final String KEY_ID = "_id";
	public static final String KEY_DATE = "date";
	public static final String KEY_DETAILS = "details";
	public static final String KEY_LOCATION_LAT = "latitude";
	public static final String KEY_LOCATION_LNG = "longitude";
	public static final String KEY_MAGNITUDE = "magnitude";
	public static final String KEY_LINK = "link";
	
	// column index
	public static final int DATE_COLUMN = 1;
	public static final int DETAILS_COLUMN = 2;
	public static final int LONGITUDE_COLUMN = 3;
	public static final int LATITUDE_COLUMN = 4;
	public static final int MAGNITUDE_COLUMN = 5;
	public static final int LINK_COLUMN = 6;
	
	private static final int QUAKES = 1;
	private static final int QUAKE_ID = 2;
	
	private static final UriMatcher uriMatcher;
	
	static {
		uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
		uriMatcher.addURI("com.company.provider.earthquake", "earthquakes", QUAKES);
		uriMatcher.addURI("com.company.provider.earthquake", "earthquakes/#", QUAKE_ID);
	}
	
	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		
		int count;
		
		switch(uriMatcher.match(uri)){
			case QUAKES :
				count = earthquakeDB.delete(EARTHQUAKE_TABLE, selection, selectionArgs);
				break;
			case QUAKE_ID :
				String segment = uri.getPathSegments().get(1);
				count = earthquakeDB.delete(EARTHQUAKE_TABLE, KEY_ID + "=" + segment + (!TextUtils.isEmpty(selection) ? "AND (" + selection + ")" : ""), selectionArgs);
				break;
			default : throw new IllegalArgumentException("Unsupported URI : " + uri);
		}
		getContext().getContentResolver().notifyChange(uri, null);		
		return count;
	}

	@Override
	public String getType(Uri uri) {
		switch (uriMatcher.match(uri)) {
		case QUAKES:
			return "vnd.android.cursor.dir/vnd.company.earthquake";		
		case QUAKE_ID:
			return "vnd.android.cursor.item/vnd.company.earthquake";
		default:
			throw new IllegalArgumentException("Unsupported URI : " + uri);
		}
	}

	@Override
	public Uri insert(Uri _uri, ContentValues values) {
		
		long rowID = earthquakeDB.insert(EARTHQUAKE_TABLE, "quake", values);
		
		if(rowID > 0){
			Uri uri = ContentUris.withAppendedId(CONTENT_URI, rowID);
			getContext().getContentResolver().notifyChange(uri, null);
			return uri;
		}		
		throw new SQLException("Failed to insert row into " + _uri);
	}

	@Override
	public boolean onCreate() {
		Context context = getContext();
		
		earthquakeDatabaseHelper dbHelper;
		dbHelper = new earthquakeDatabaseHelper(context, DATABASE_NAME, null, DATABASE_VERSION);
		earthquakeDB = dbHelper.getWritableDatabase();
		return (earthquakeDB == null) ? false : true;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		
		SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
		qb.setTables(EARTHQUAKE_TABLE);
		
		switch(uriMatcher.match(uri)){
			case QUAKE_ID :
				qb.appendWhere(KEY_ID + "=" + uri.getPathSegments().get(1)); 
				break;
			default: break;
		}
		
		String orderBy;
		if(TextUtils.isEmpty(sortOrder))
			orderBy = KEY_DATE;
		else
			orderBy = sortOrder;
		
		Cursor c = qb.query(earthquakeDB, projection, selection, selectionArgs, null, null, orderBy);
		
		c.setNotificationUri(getContext().getContentResolver(), uri);
		
		return c;
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		
		int count;
		
		switch(uriMatcher.match(uri)){
			case QUAKES :
				count = earthquakeDB.update(EARTHQUAKE_TABLE, values, selection, selectionArgs);
				break;
				
			case QUAKE_ID :
				String segment = uri.getPathSegments().get(1);
				count = earthquakeDB.update(EARTHQUAKE_TABLE, values, KEY_ID + "=" + segment + (!TextUtils.isEmpty(selection) ? "AND (" + selection + ")" : ""), selectionArgs);
				break;
			default : throw new IllegalArgumentException("Unknown URI" + uri);
		}
		getContext().getContentResolver().notifyChange(uri, null);
		return count;
	}
	
	private static class earthquakeDatabaseHelper extends SQLiteOpenHelper {
		
		private static final String DATABASE_CREATE = 
			"create table " + EARTHQUAKE_TABLE + " ("
			+ KEY_ID + " integer primary key autoincrement, "
			+ KEY_DATE + " INTEGER, "
			+ KEY_DETAILS + " TEXT, "
			+ KEY_LOCATION_LAT + " FLOAT, "
			+ KEY_LOCATION_LNG + " FLOAT, "
			+ KEY_MAGNITUDE + " FLOAT, "
			+ KEY_LINK + " TEXT); ";
			

		public earthquakeDatabaseHelper(Context context, String name,
				CursorFactory factory, int version) {
			super(context, name, factory, version);
		}

		@Override
		public void onCreate(SQLiteDatabase db) {
			db.execSQL(DATABASE_CREATE);
		}

		@Override
		public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
			Log.w(TAG, "Upgrading database from version" + oldVersion + " to" + newVersion + ", which will destroy all old data");
			db.execSQL("DROP TABLE IF EXISTS " + EARTHQUAKE_TABLE);
			onCreate(db);
		}		
	}
}
